using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Diagnostics;
using System.Management;
using System.Runtime.InteropServices;
using System.Text.Json;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Services.Monitoring
{
    /// <summary>
    /// 系统性能监控服务
    /// 提供CPU、内存、磁盘、网络等系统资源监控功能
    /// </summary>
    public class SystemPerformanceMonitor : ISystemPerformanceMonitor, IDisposable
    {
        private readonly SystemPerformanceOptions _options;
        private readonly ILogger<SystemPerformanceMonitor> _logger;
    private Timer? _monitoringTimer;
        private readonly PerformanceCounter? _cpuCounter;
        private readonly PerformanceCounter? _memoryCounter;
        private readonly PerformanceCounter? _diskCounter;
        private readonly List<PerformanceMetric> _metrics;
        private readonly object _metricsLock = new();
        private bool _disposed;

        public SystemPerformanceMonitor(
            IOptions<SystemPerformanceOptions> options, 
            ILogger<SystemPerformanceMonitor> logger)
        {
            _options = options?.Value ?? throw new ArgumentNullException(nameof(options));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
            _metrics = new List<PerformanceMetric>();

            try
            {
                // 初始化性能计数器
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    _cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
                    _memoryCounter = new PerformanceCounter("Memory", "Available MBytes");
                    _diskCounter = new PerformanceCounter("PhysicalDisk", "% Disk Time", "_Total");
                }

                // 启动监控定时器
                if (_options.AutoStart)
                {
                    _monitoringTimer = new Timer(CollectMetrics, null,
                        TimeSpan.Zero, TimeSpan.FromSeconds(_options.CollectionIntervalSeconds));
                }

                _logger.LogInformation("系统性能监控服务已启动，采集间隔: {Interval}秒", _options.CollectionIntervalSeconds);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "初始化系统性能监控服务失败");
            }
        }

        /// <summary>
        /// 获取当前系统性能信息
        /// </summary>
        public async Task<SystemPerformanceInfo> GetCurrentPerformanceAsync()
        {
            try
            {
                var performanceInfo = new SystemPerformanceInfo
                {
                    Timestamp = DateTime.UtcNow,
                    CpuUsagePercent = await GetCpuUsageAsync(),
                    MemoryUsagePercent = await GetMemoryUsageAsync(),
                    MemoryUsedMB = await GetMemoryUsedMBAsync(),
                    MemoryTotalMB = await GetMemoryTotalMBAsync(),
                    DiskUsagePercent = await GetDiskUsageAsync(),
                    DiskUsedGB = await GetDiskUsedGBAsync(),
                    DiskTotalGB = await GetDiskTotalGBAsync(),
                    ProcessCount = Process.GetProcesses().Length,
                    ThreadCount = await GetThreadCountAsync(),
                    HandleCount = await GetHandleCountAsync(),
                    UptimeMinutes = (int)TimeSpan.FromMilliseconds(Environment.TickCount64).TotalMinutes,
                    NetworkConnectionCount = await GetNetworkConnectionCountAsync()
                };

                // 计算性能等级
                performanceInfo.PerformanceLevel = CalculatePerformanceLevel(performanceInfo);

                return performanceInfo;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取系统性能信息失败");
                return new SystemPerformanceInfo
                {
                    Timestamp = DateTime.UtcNow,
                    PerformanceLevel = PerformanceLevel.Unknown
                };
            }
        }

        /// <summary>
        /// 获取性能历史记录
        /// </summary>
        public Task<IEnumerable<PerformanceMetric>> GetMetricsHistoryAsync(TimeSpan period)
        {
            lock (_metricsLock)
            {
                var cutoffTime = DateTime.UtcNow.Subtract(period);
                var filteredMetrics = _metrics
                    .Where(m => m.Timestamp >= cutoffTime)
                    .OrderBy(m => m.Timestamp)
                    .ToList();

                return Task.FromResult<IEnumerable<PerformanceMetric>>(filteredMetrics);
            }
        }

        /// <summary>
        /// 获取性能统计信息
        /// </summary>
        public Task<PerformanceStatistics> GetPerformanceStatisticsAsync(TimeSpan period)
        {
            lock (_metricsLock)
            {
                var cutoffTime = DateTime.UtcNow.Subtract(period);
                var relevantMetrics = _metrics
                    .Where(m => m.Timestamp >= cutoffTime)
                    .ToList();

                if (!relevantMetrics.Any())
                {
                    return Task.FromResult(new PerformanceStatistics
                    {
                        StartTime = DateTime.UtcNow,
                        EndTime = DateTime.UtcNow,
                        TotalSamples = 0
                    });
                }

                var statistics = new PerformanceStatistics
                {
                    StartTime = relevantMetrics.Min(m => m.Timestamp),
                    EndTime = relevantMetrics.Max(m => m.Timestamp),
                    TotalSamples = relevantMetrics.Count,
                    
                    AverageCpuUsage = relevantMetrics.Average(m => m.CpuUsagePercent),
                    MaxCpuUsage = relevantMetrics.Max(m => m.CpuUsagePercent),
                    MinCpuUsage = relevantMetrics.Min(m => m.CpuUsagePercent),
                    
                    AverageMemoryUsage = relevantMetrics.Average(m => m.MemoryUsagePercent),
                    MaxMemoryUsage = relevantMetrics.Max(m => m.MemoryUsagePercent),
                    MinMemoryUsage = relevantMetrics.Min(m => m.MemoryUsagePercent),
                    
                    AverageDiskUsage = relevantMetrics.Average(m => m.DiskUsagePercent),
                    MaxDiskUsage = relevantMetrics.Max(m => m.DiskUsagePercent),
                    MinDiskUsage = relevantMetrics.Min(m => m.DiskUsagePercent)
                };

                return Task.FromResult(statistics);
            }
        }

        /// <summary>
        /// 检查系统性能警告
        /// </summary>
        public async Task<IEnumerable<PerformanceAlert>> CheckPerformanceAlertsAsync()
        {
            var alerts = new List<PerformanceAlert>();
            var currentPerformance = await GetCurrentPerformanceAsync();

            try
            {
                // CPU使用率警告
                if (currentPerformance.CpuUsagePercent > _options.CpuWarningThreshold)
                {
                    alerts.Add(new PerformanceAlert
                    {
                        Type = AlertType.CpuUsage,
                        Level = currentPerformance.CpuUsagePercent > _options.CpuCriticalThreshold 
                            ? AlertLevel.Critical : AlertLevel.Warning,
                        Message = $"CPU使用率过高: {currentPerformance.CpuUsagePercent:F1}%",
                        Value = currentPerformance.CpuUsagePercent,
                        Threshold = _options.CpuWarningThreshold,
                        Timestamp = DateTime.UtcNow
                    });
                }

                // 内存使用率警告
                if (currentPerformance.MemoryUsagePercent > _options.MemoryWarningThreshold)
                {
                    alerts.Add(new PerformanceAlert
                    {
                        Type = AlertType.MemoryUsage,
                        Level = currentPerformance.MemoryUsagePercent > _options.MemoryCriticalThreshold 
                            ? AlertLevel.Critical : AlertLevel.Warning,
                        Message = $"内存使用率过高: {currentPerformance.MemoryUsagePercent:F1}%",
                        Value = currentPerformance.MemoryUsagePercent,
                        Threshold = _options.MemoryWarningThreshold,
                        Timestamp = DateTime.UtcNow
                    });
                }

                // 磁盘使用率警告
                if (currentPerformance.DiskUsagePercent > _options.DiskWarningThreshold)
                {
                    alerts.Add(new PerformanceAlert
                    {
                        Type = AlertType.DiskUsage,
                        Level = currentPerformance.DiskUsagePercent > _options.DiskCriticalThreshold 
                            ? AlertLevel.Critical : AlertLevel.Warning,
                        Message = $"磁盘使用率过高: {currentPerformance.DiskUsagePercent:F1}%",
                        Value = currentPerformance.DiskUsagePercent,
                        Threshold = _options.DiskWarningThreshold,
                        Timestamp = DateTime.UtcNow
                    });
                }

                // 记录警告日志
                foreach (var alert in alerts)
                {
                    if (alert.Level == AlertLevel.Critical)
                    {
                        _logger.LogError("系统性能严重警告: {Message}", alert.Message);
                    }
                    else
                    {
                        _logger.LogWarning("系统性能警告: {Message}", alert.Message);
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "检查系统性能警告时发生异常");
            }

            return alerts;
        }

        /// <summary>
        /// 开始监控
        /// </summary>
        public Task StartMonitoringAsync()
        {
            if (_disposed)
            {
                return Task.CompletedTask;
            }

            if (_monitoringTimer == null)
            {
                _logger.LogInformation("开始系统性能监控");
                _monitoringTimer = new Timer(CollectMetrics, null,
                    TimeSpan.Zero, TimeSpan.FromSeconds(_options.CollectionIntervalSeconds));
            }
            else
            {
                _logger.LogInformation("系统性能监控已在运行");
            }

            return Task.CompletedTask;
        }

        /// <summary>
        /// 停止监控
        /// </summary>
        public Task StopMonitoringAsync()
        {
            _monitoringTimer?.Change(Timeout.Infinite, Timeout.Infinite);
            _logger.LogInformation("系统性能监控已停止");
            return Task.CompletedTask;
        }

        /// <summary>
        /// 采集指标数据
        /// </summary>
        private async void CollectMetrics(object? state)
        {
            try
            {
                var performance = await GetCurrentPerformanceAsync();
                var metric = new PerformanceMetric
                {
                    Timestamp = performance.Timestamp,
                    CpuUsagePercent = performance.CpuUsagePercent,
                    MemoryUsagePercent = performance.MemoryUsagePercent,
                    DiskUsagePercent = performance.DiskUsagePercent,
                    ProcessCount = performance.ProcessCount,
                    ThreadCount = performance.ThreadCount,
                    HandleCount = performance.HandleCount,
                    PerformanceLevel = performance.PerformanceLevel
                };

                lock (_metricsLock)
                {
                    _metrics.Add(metric);
                    
                    // 清理旧数据，只保留指定天数的数据
                    var cutoffTime = DateTime.UtcNow.AddDays(-_options.RetentionDays);
                    _metrics.RemoveAll(m => m.Timestamp < cutoffTime);

                    // 限制内存中的数据量
                    if (_metrics.Count > _options.MaxMetricsInMemory)
                    {
                        var removeCount = _metrics.Count - _options.MaxMetricsInMemory;
                        _metrics.RemoveRange(0, removeCount);
                    }
                }

                // 检查性能警告
                if (_options.EnableAlerts)
                {
                    _ = Task.Run(async () =>
                    {
                        try
                        {
                            await CheckPerformanceAlertsAsync();
                        }
                        catch (Exception ex)
                        {
                            _logger.LogError(ex, "检查性能警告时发生异常");
                        }
                    });
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "采集系统性能指标时发生异常");
            }
        }

        /// <summary>
        /// 获取CPU使用率
        /// </summary>
        private async Task<float> GetCpuUsageAsync()
        {
            try
            {
                if (_cpuCounter != null && RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    return _cpuCounter.NextValue();
                }
                else
                {
                    // 跨平台CPU使用率获取
                    return await GetCrossPlatformCpuUsageAsync();
                }
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "获取CPU使用率失败");
                return 0;
            }
        }

        /// <summary>
        /// 跨平台获取CPU使用率
        /// </summary>
        private async Task<float> GetCrossPlatformCpuUsageAsync()
        {
            try
            {
                var startTime = DateTime.UtcNow;
                var startCpuUsage = Process.GetCurrentProcess().TotalProcessorTime;

                await Task.Delay(1000);

                var endTime = DateTime.UtcNow;
                var endCpuUsage = Process.GetCurrentProcess().TotalProcessorTime;

                var cpuUsedMs = (endCpuUsage - startCpuUsage).TotalMilliseconds;
                var totalMsPassed = (endTime - startTime).TotalMilliseconds;
                var cpuUsageTotal = cpuUsedMs / (Environment.ProcessorCount * totalMsPassed) * 100;

                return (float)cpuUsageTotal;
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// 获取内存使用率
        /// </summary>
        private async Task<float> GetMemoryUsageAsync()
        {
            try
            {
                var totalMemory = await GetMemoryTotalMBAsync();
                var usedMemory = await GetMemoryUsedMBAsync();
                
                if (totalMemory > 0)
                {
                    return (usedMemory / totalMemory) * 100;
                }
                
                return 0;
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "获取内存使用率失败");
                return 0;
            }
        }

        /// <summary>
        /// 获取已使用内存(MB)
        /// </summary>
        private async Task<float> GetMemoryUsedMBAsync()
        {
            try
            {
                if (_memoryCounter != null && RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    var availableMemory = _memoryCounter.NextValue();
                    var totalMemory = await GetMemoryTotalMBAsync();
                    return totalMemory - availableMemory;
                }
                else
                {
                    // 使用GC信息估算
                    var totalMemory = GC.GetTotalMemory(false);
                    return totalMemory / (1024 * 1024); // 转换为MB
                }
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "获取已使用内存失败");
                return 0;
            }
        }

        /// <summary>
        /// 获取总内存(MB)
        /// </summary>
    private Task<float> GetMemoryTotalMBAsync()
        {
            try
            {
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    using var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_ComputerSystem");
                    foreach (ManagementObject obj in searcher.Get())
                    {
                        var totalPhysicalMemory = Convert.ToUInt64(obj["TotalPhysicalMemory"]);
            return Task.FromResult((float)(totalPhysicalMemory / (1024 * 1024))); // 转换为MB
                    }
                }
                
                // 默认返回近似值
        return Task.FromResult((float)(Environment.WorkingSet / (1024 * 1024)));
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "获取总内存失败");
        return Task.FromResult(0f);
            }
        }

        /// <summary>
        /// 获取磁盘使用率
        /// </summary>
        private Task<float> GetDiskUsageAsync()
        {
            try
            {
                if (_diskCounter != null && RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    return Task.FromResult(_diskCounter.NextValue());
                }
                else
                {
                    // 获取根目录磁盘使用情况
                    var driveInfo = new DriveInfo("/");
                    if (driveInfo.IsReady)
                    {
                        var usedSpace = driveInfo.TotalSize - driveInfo.AvailableFreeSpace;
                        return Task.FromResult(((float)usedSpace / driveInfo.TotalSize) * 100);
                    }
                    
                    return Task.FromResult(0f);
                }
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "获取磁盘使用率失败");
                return Task.FromResult(0f);
            }
        }

        /// <summary>
        /// 获取已使用磁盘空间(GB)
        /// </summary>
        private Task<float> GetDiskUsedGBAsync()
        {
            try
            {
                var driveInfo = new DriveInfo("/");
                if (driveInfo.IsReady)
                {
                    var usedSpace = driveInfo.TotalSize - driveInfo.AvailableFreeSpace;
                    return Task.FromResult(usedSpace / (1024 * 1024 * 1024f)); // 转换为GB
                }
                
                return Task.FromResult(0f);
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "获取已使用磁盘空间失败");
                return Task.FromResult(0f);
            }
        }

        /// <summary>
        /// 获取磁盘总空间(GB)
        /// </summary>
        private Task<float> GetDiskTotalGBAsync()
        {
            try
            {
                var driveInfo = new DriveInfo("/");
                if (driveInfo.IsReady)
                {
                    return Task.FromResult(driveInfo.TotalSize / (1024 * 1024 * 1024f)); // 转换为GB
                }
                
                return Task.FromResult(0f);
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "获取磁盘总空间失败");
                return Task.FromResult(0f);
            }
        }

        /// <summary>
        /// 获取线程总数
        /// </summary>
    private Task<int> GetThreadCountAsync()
        {
            try
            {
        var count = Process.GetProcesses().Sum(p => 
                {
                    try 
                    { 
                        return p.Threads.Count; 
                    } 
                    catch 
                    { 
                        return 0; 
                    }
                });
        return Task.FromResult(count);
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "获取线程总数失败");
        return Task.FromResult(0);
            }
        }

        /// <summary>
        /// 获取句柄总数
        /// </summary>
    private Task<int> GetHandleCountAsync()
        {
            try
            {
        var count = Process.GetProcesses().Sum(p => 
                {
                    try 
                    { 
                        return p.HandleCount; 
                    } 
                    catch 
                    { 
                        return 0; 
                    }
                });
        return Task.FromResult(count);
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "获取句柄总数失败");
        return Task.FromResult(0);
            }
        }

        /// <summary>
        /// 获取网络连接数
        /// </summary>
    private Task<int> GetNetworkConnectionCountAsync()
        {
            try
            {
                // 这里可以实现更复杂的网络连接统计
                // 暂时返回估算值
        return Task.FromResult(Environment.ProcessorCount * 10);
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "获取网络连接数失败");
        return Task.FromResult(0);
            }
        }

        /// <summary>
        /// 计算性能等级
        /// </summary>
        private PerformanceLevel CalculatePerformanceLevel(SystemPerformanceInfo info)
        {
            var issues = 0;

            if (info.CpuUsagePercent > _options.CpuCriticalThreshold) issues += 3;
            else if (info.CpuUsagePercent > _options.CpuWarningThreshold) issues += 1;

            if (info.MemoryUsagePercent > _options.MemoryCriticalThreshold) issues += 3;
            else if (info.MemoryUsagePercent > _options.MemoryWarningThreshold) issues += 1;

            if (info.DiskUsagePercent > _options.DiskCriticalThreshold) issues += 2;
            else if (info.DiskUsagePercent > _options.DiskWarningThreshold) issues += 1;

            return issues switch
            {
                0 => PerformanceLevel.Excellent,
                1 => PerformanceLevel.Good,
                2 or 3 => PerformanceLevel.Fair,
                4 or 5 => PerformanceLevel.Poor,
                _ => PerformanceLevel.Critical
            };
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            if (_disposed) return;

            _monitoringTimer?.Dispose();
            _cpuCounter?.Dispose();
            _memoryCounter?.Dispose();
            _diskCounter?.Dispose();
            
            _disposed = true;
        }
    }
}
